package com.xiaotu.spider.youku.pageprocessor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.TVDanMuCommentModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.HttpUtils;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;

/**
 * 优酷视频弹幕爬取
 * @author wangyanlong
 * @date 2019年7月26日 下午4:56:18
 *
 */
@Component("YouKuDanMuPageProcessor")
@Scope("prototype")
public class YouKuDanMuPageProcessor extends APageProcessor
{
	private String requRL = "http://service.danmu.youku.com/list?mat=%s&mcount=1&ct=1001&iid=%s&aid=%s&cid=96&lid=0&ouid=0";
	
    @Override
    protected Request getStartRequest(JSONObject target)
    {
        return new Request("https://so.youku.com/search_video/q_"+KeywordEncode.encode(target.getString("tvName")));
    }

    @Override
    public void process(Page page)
    {
        Map<String, Object> tvMap = page.getRequest().getExtras();
        switch (this.getPageDataType(page))
        {
            case Constants.PageDataType.SEARCH_LIST:
                this.searchListProcess(page, tvMap);
                break;
            case Constants.PageDataType.BASICINFO:
                this.tvDetailList(page,tvMap);
                break;
            case Constants.PageDataType.TV_RECORD:
                this.tvRecord(page,tvMap);
                break;
            default:
                break;
        }
    }

    private void searchListProcess(Page page, Map<String, Object> tvMap){
    	
		try {
			Connection conn = connent(page.getUrl().toString());
			conn.get();
			Response rs = conn.response();
			String html = rs.body();
			String searchList = html.substring(html.indexOf("\"html\":\"")+8).replace("\\n", "").replace("\\t", "").replace("\\\"", "");
			if(StringUtil.isNotEmpty(searchList)){
				//searchList =searchList.replace("\\n", "").replace("\\t", "").replace("\\\"", "");
				System.out.println(searchList);
				Document documentList = Jsoup.parse(searchList,"utf8");
				
				Elements elments = documentList.select(".sk-result-list .sk-mod");
				for (Element element : elments) {
					System.out.println(element);
					String tvName = element.select(".mod-main .mod-header .spc-lv-1").select("a").attr("title");
					if(StringUtil.isNotEmpty(tvName)){
		            	tvName = RegexUtils.regexChStr(tvName).trim();
		            }
					String tvType = element.select(".mod-main .mod-header .base-type").text();
					if(StringUtil.isNotEmpty(tvType) && tvType.equals("剧集")){
						tvType = "电视剧";
					}
					Elements peopleList = element.select(".mod-main .mod-info").select("p").select("span[class=spc-lv-4]");
					boolean dirFlage = false;
					boolean actorFlage = false;
					for (Element peopleDiv: peopleList) {
						String peopleType = peopleDiv.select("label").text();
						if(peopleType !=null && peopleType.contains("导演")){
							Elements directorList = peopleDiv.select("span").select("a");
							for (Element directorDiv : directorList) {
								String director = directorDiv.select("a").text();
								if(StringUtil.isNotEmpty(director) && tvMap.get("director").toString().contains(director)){
									dirFlage =true;
									break;
								}
							}
							
						}else if(peopleType !=null && peopleType.contains("主演")){
							Elements actorList = peopleDiv.select("span").select("a");
							for (Element actorDiv : actorList) {
								String actor = actorDiv.select("a").text();
								if(StringUtil.isNotEmpty(actor) && tvMap.get("actor").toString().contains(actor)){
									actorFlage =true;
									break;
								}
							}
						}
						
					}
					String tvOldName = tvMap.get("tvName")+"";
		            if(StringUtil.isNotEmpty(tvOldName)){
		            	tvOldName = RegexUtils.regexChStr(tvOldName).trim();
		            }
					if(tvOldName.equals(tvName) 
							&& tvMap.get("tvType").toString().equals(tvType) 
							&& dirFlage && actorFlage){
						String url = element.select(".mod-header .spc-lv-1").select("a").attr("href");
						PageUtils.addTargetRequest(page, url, tvMap);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
        
    }

    private void tvDetailList(Page page, Map<String, Object> tvMap) {
    	String divList = page.getRawText();
    	String showId = divList.substring(divList.indexOf("showid:"), divList.indexOf("cp:"));
    	showId = RegexUtils.regexSearch(RegexUtils.REGEX_INTEGER, showId);
    	String vidJsons = divList.substring(divList.indexOf("window.playerAnthology="), divList.indexOf("if (window.videoPlayer "));
    	if(StringUtil.isNotEmpty(vidJsons)){
    		vidJsons = vidJsons.replace("window.playerAnthology=", "");
    		vidJsons = vidJsons.substring(0, vidJsons.lastIndexOf(";"));
    	}
    	JSONObject searchJson = JSONObject.fromObject(vidJsons);
    	JSONArray jsonArray = searchJson.getJSONArray("list");
    	for (int i = 0; i < jsonArray.size(); i++) {
    		String vid = jsonArray.getJSONObject(i).getString("vid");
    		String url ="http://service.danmu.youku.com/list?mat=1&mcount=1&ct=1001&iid="+vid+"&aid="+showId+"&cid=96&lid=0&ouid=0";
    		PageUtils.addTargetRequest(page, url, tvMap);
		}
    }
    
    private void tvRecord(Page page, Map<String, Object> tvMap) {
    	String url = page.getUrl().toString();
    	String vid = url.substring(url.indexOf("iid=")+4,url.indexOf("&aid"));
    	String cid = url.substring(url.indexOf("aid=")+4);
    	List<TVDanMuCommentModel> resList = new ArrayList<TVDanMuCommentModel>();
    	for(int mat=0;mat<=60;mat++){
			String httpDanMuJSONP = HttpUtils.httpGetJSONP(String.format(requRL,mat,vid,cid));
			if (StringUtil.isEmpty(httpDanMuJSONP))
				throw new SpiderException(
						SpiderExceptionCode.DataInvalideException);
			
			JSONObject searchJson = JSONObject.fromObject(httpDanMuJSONP);
			
			List<String> datas = searchJson.getJSONArray("result");
			if(StringUtil.isNotEmpty(datas) && datas.size()==0){
				break;
			}
				JSONArray comentList = searchJson.getJSONArray("result");
				for (Object coments : comentList) {
					JSONObject comment = JSONObject.fromObject(coments);
					String content = comment.getString("content");
					if(StringUtil.isNotEmpty(content)){
						content = content.replaceAll("[^(0-9a-zA-Z\u4e00-\u9fa5\\p{P}\r\n )]","");
					}
					String up= comment.getJSONObject("extFields").getString("voteUp");
					
					resList.add(new TVDanMuCommentModel(tvMap.get("tvName")+"",
							comment.getString("ouid"),"",content,"",comment.getString("createtime"),
							up,"优酷")); 
				}
		}
		    	page.putField(TVDanMuCommentModel.class.getName(), resList);
    }
    //链接目标url
  	public static Connection connent(String url) {
      	Connection conn = Jsoup.connect(url)    
                  .userAgent("Mozilla/5.0 (Windows NT 6.1; rv:47.0) Gecko/20100101 Firefox/47.0") // http请求的浏览器设置
                  .timeout(5000)   // http连接时长
                  .maxBodySize(0)
                  .method(Connection.Method.GET);  // 请求类型是get请求，http请求还是post,delete等方式   	
      	return conn;
      }	
    
    @Override
    public String getSpiderType()
    {
        return Constants.SpiderTaskType.YOUKU_TV_DANMU;
    }

    @Override
    public String getPageDataType(Page page)
    {
        String url = page.getUrl().toString();
        if (url.contains("so.youku.com/search_video"))
            return Constants.PageDataType.SEARCH_LIST;
        else if (url.contains("v.youku.com/v_show/id_"))
        	 return Constants.PageDataType.BASICINFO;
        else if (url.contains("service.danmu.youku.com"))
        	return Constants.PageDataType.TV_RECORD;
        return Constants.PageDataType.TV_COMMENT;
    }
    
}
